package com.onlygx.dva.common.executor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * @Description 线程池的配置
 * @ClassName AsyncConfig
 * @Author 刘芳
 * @date 2022.03.17 10:07
 */
@Slf4j
@Configuration
@EnableAsync
public class AsyncConfig {

    private static final int MAX_POOL_SIZE = 10;

    private static final int CORE_POOL_SIZE = 5;

    private static final int KEEP_ALIVE_SECONDS = 300;

    private static final int QUERY_CAPACITY = 1000;

    @Bean("asyncTaskExecutor")
    public AsyncTaskExecutor asyncTaskExecutor() {
        ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
        /** 线程池维护线程的最大数量 **/
        /** 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务 **/
        /** 当线程数=maxPoolSize,且任务队列已满时，线程池会拒绝处理任务而抛出异常 **/
        asyncTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        /** 线程池维护线程的最少数量，即使没有任务需要执行，也会一直存活 **/
        /** 设置allowCoreThreadTimeout=true（默认false）时，核心线程会超时关闭 **/
        asyncTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
        /** 允许的空闲时间，当线程空闲时间达到keepAliveTime时，线程会退出，直到线程数量=corePoolSize **/
        /** 如果allowCoreThreadTimeout=ture，则会直到线程数量=0 **/
        asyncTaskExecutor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
        asyncTaskExecutor.setAllowCoreThreadTimeOut(true);
        /** 缓存队列（阻塞队列）当核心线程数达到最大时，新任务会放在队列中排队等待执行 **/
        asyncTaskExecutor.setQueueCapacity(QUERY_CAPACITY);
        /** 拒绝策略CallerRunsPolicy：如果添加到线程池失败，丢掉这个任务并且抛出RejectedExecutionException异常**/
        asyncTaskExecutor.setRejectedExecutionHandler((r, executor) -> log.error("异步线程池队列满载，抛出异常ReflectiveOperationException:Task " + r.toString() + " rejected from " + executor.toString()));
        asyncTaskExecutor.setThreadNamePrefix("async-task-thread-pool-");
        asyncTaskExecutor.initialize();
        return asyncTaskExecutor;
    }

    @Bean("asyncOneTaskExecutor")
    public AsyncTaskExecutor asyncOneTaskExecutor() {
        ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
        /** 线程池维护线程的最大数量 **/
        /** 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务 **/
        /** 当线程数=maxPoolSize,且任务队列已满时，线程池会拒绝处理任务而抛出异常 **/
        asyncTaskExecutor.setMaxPoolSize(1);
        /** 线程池维护线程的最少数量，即使没有任务需要执行，也会一直存活 **/
        /** 设置allowCoreThreadTimeout=true（默认false）时，核心线程会超时关闭 **/
        asyncTaskExecutor.setCorePoolSize(1);
        /** 允许的空闲时间，当线程空闲时间达到keepAliveTime时，线程会退出，直到线程数量=corePoolSize **/
        /** 如果allowCoreThreadTimeout=ture，则会直到线程数量=0 **/
        asyncTaskExecutor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
        asyncTaskExecutor.setAllowCoreThreadTimeOut(true);
        /** 缓存队列（阻塞队列）当核心线程数达到最大时，新任务会放在队列中排队等待执行 **/
        asyncTaskExecutor.setQueueCapacity(QUERY_CAPACITY);
        /** 拒绝策略CallerRunsPolicy：如果添加到线程池失败，丢掉这个任务并且抛出RejectedExecutionException异常**/
        asyncTaskExecutor.setRejectedExecutionHandler((r, executor) -> log.error("异步线程池队列满载，抛出异常ReflectiveOperationException:Task " + r.toString() + " rejected from " + executor.toString()));
        asyncTaskExecutor.setThreadNamePrefix("async-one-task-thread-pool-");
        asyncTaskExecutor.initialize();
        return asyncTaskExecutor;
    }

}
